package com.industrial.operation.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.industrial.common.core.utils.DateUtils;
import com.industrial.common.core.utils.uuid.IdUtils;
import com.industrial.common.core.web.domain.AjaxResult;
import com.industrial.common.security.utils.SecurityUtils;
import com.industrial.operation.domain.*;
import com.industrial.operation.mapper.*;
import com.industrial.system.api.domain.SysRole;
import com.industrial.system.api.domain.SysUser;
import com.industrial.operation.contents.RoleContents;
import com.industrial.operation.service.ISysDataReportingService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 数据上报Service业务层处理
 *
 * @author SangGuangCan
 * @date 2024-01-18
 */
@Service
public class SysDataReportingServiceImpl implements ISysDataReportingService
{
    @Autowired
    private SysDataReportingMapper sysDataReportingMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SysDataReportingScoreMapper sysDataReportingScoreMapper;


    @Autowired
    private SysDataReportingScoreAppealMapper sysDataReportingScoreAppealMapper;

    @Autowired
    private SysDataReportingFileMapper sysDataReportingFileMapper;

    @Autowired
    private SysDataReportingScoreAppealFileMapper sysDataReportingScoreAppealFileMapper;

    @Value("${file.domain}")
    private String fileDomain;

    /**
     * 查询数据上报
     *
     * @param baseId 数据上报主键
     * @return 数据上报
     */
    @Override
    public SysDataReporting selectSysDataReportingByBaseId(String baseId)
    {
        SysDataReporting sysDataReporting = sysDataReportingMapper.selectSysDataReportingByBaseId(baseId);
        List<String> address = new ArrayList<>();

        if(StringUtils.isNotBlank(sysDataReporting.getProvince())
                && StringUtils.isNotBlank(sysDataReporting.getCity())
                && StringUtils.isNotBlank(sysDataReporting.getDistrict())){
            address.add(sysDataReporting.getProvince());
            address.add(sysDataReporting.getCity());
            address.add(sysDataReporting.getDistrict());
        }else if(StringUtils.isNotBlank(sysDataReporting.getProvince()) && StringUtils.isNotBlank(sysDataReporting.getCity())){
            address.add(sysDataReporting.getProvince());
            address.add(sysDataReporting.getCity());
        }else if(StringUtils.isNotBlank(sysDataReporting.getProvince())){
            address.add(sysDataReporting.getProvince());
        }
        sysDataReporting.setAddress(address);
        return sysDataReporting;
    }

    /**
     * 查询数据上报列表
     *
     * @param sysDataReporting 数据上报
     * @return 数据上报
     */
    @Override
    public List<SysDataReporting> selectSysDataReportingList(SysDataReporting sysDataReporting)
    {
        List<String> addressArgs = sysDataReporting.getAddress();
        if(addressArgs != null && !addressArgs.isEmpty()){
            if(addressArgs.size() == 1){
                sysDataReporting.setProvince(addressArgs.get(0));
            }else if(addressArgs.size() == 2){
                sysDataReporting.setProvince(addressArgs.get(0));
                sysDataReporting.setCity(addressArgs.get(1));
            }else if(addressArgs.size() == 3){
                sysDataReporting.setProvince(addressArgs.get(0));
                sysDataReporting.setCity(addressArgs.get(1));
                sysDataReporting.setDistrict(addressArgs.get(2));
            }
        }

        List<SysDataReporting> sysDataReportings = sysDataReportingMapper.selectSysDataReportingList(sysDataReporting);
        for(SysDataReporting item : sysDataReportings){
            String province = item.getProvince();
            String city = item.getCity();
            String district = item.getDistrict();

            StringBuilder address = new StringBuilder();

            if(StringUtils.isNotBlank(province)){
                String provinceName = redisTemplate.opsForValue().get("area:" + province);
                address.append(provinceName);
            }

            if(StringUtils.isNotBlank(city)){
                String cityName = redisTemplate.opsForValue().get("area:" + city);
                address.append("-").append(cityName);
            }

            if(StringUtils.isNotBlank(district)){
                String districtName = redisTemplate.opsForValue().get("area:" + district);
                address.append("-").append(districtName);
            }
            item.setAddressArea(address.toString());
        }
        return sysDataReportings;
    }

    /**
     * 新增数据上报
     *
     * @param sysDataReporting 数据上报
     * @return 结果
     */
    @Override
    public int insertSysDataReporting(SysDataReporting sysDataReporting)
    {
        sysDataReporting.setBaseId(IdUtils.simpleUUID());
        Date nowDate = DateUtils.getNowDate();
        sysDataReporting.setBaseCreateTime(nowDate);
        sysDataReporting.setBaseCreateBy(SecurityUtils.getUserId());
        List<String> address = sysDataReporting.getAddress();
        if(address.size() != 3){
            throw new RuntimeException("请选择要上报的区县");
        }
        if(address != null && !address.isEmpty()){
            if(address.size() == 1){
                sysDataReporting.setProvince(address.get(0));
            }else if(address.size() == 2){
                sysDataReporting.setProvince(address.get(0));
                sysDataReporting.setCity(address.get(1));
            }else if(address.size() == 3){
                sysDataReporting.setProvince(address.get(0));
                sysDataReporting.setCity(address.get(1));
                sysDataReporting.setDistrict(address.get(2));
            }
        }

        int year = DateUtil.year(nowDate) -  1;
        SysDataReporting params = new SysDataReporting();
        params.setProvince(sysDataReporting.getProvince());
        params.setCity(sysDataReporting.getCity());
        params.setDistrict(sysDataReporting.getDistrict());
        params.setYear(String.valueOf(year));

        List<SysDataReporting> oldSysDataReporting = sysDataReportingMapper.selectSysDataReportingList(params);
        if(oldSysDataReporting != null && !oldSysDataReporting.isEmpty()){
            String s = redisTemplate.opsForValue().get("area:" + params.getProvince());
            String c = redisTemplate.opsForValue().get("area:" + params.getCity());
            String d = redisTemplate.opsForValue().get("area:" + params.getDistrict());
            throw new RuntimeException(String.format("%s-%s-%s在%d年已经提报过数据，无须在次提交",s,c,d,year));
        }
        sysDataReporting.setYear(String.valueOf(year));
        sysDataReporting.setCheckStatus("0");
        return sysDataReportingMapper.insertSysDataReporting(sysDataReporting);
    }

    /**
     * 修改数据上报
     *
     * @param sysDataReporting 数据上报
     * @return 结果
     */
    @Override
    public int updateSysDataReporting(SysDataReporting sysDataReporting)
    {
        List<String> address = sysDataReporting.getAddress();
        if(address != null && !address.isEmpty()){
            if(address.size() == 1){
                sysDataReporting.setProvince(address.get(0));
            }else if(address.size() == 2){
                sysDataReporting.setProvince(address.get(0));
                sysDataReporting.setCity(address.get(1));
            }else if(address.size() == 3){
                sysDataReporting.setProvince(address.get(0));
                sysDataReporting.setCity(address.get(1));
                sysDataReporting.setDistrict(address.get(2));
            }
        }
        sysDataReporting.setCheckStatus("0");
        return sysDataReportingMapper.updateSysDataReporting(sysDataReporting);
    }

    /**
     * 批量删除数据上报
     *
     * @param baseIds 需要删除的数据上报主键
     * @return 结果
     */
    @Override
    public int deleteSysDataReportingByBaseIds(String[] baseIds)
    {
        if(baseIds.length <= 0){
            throw new RuntimeException("您没有指定要删除的数据");
        }
        SysDataReportingScoreAppeal params = new SysDataReportingScoreAppeal();
        params.setPkId(baseIds[0]);
        List<SysDataReportingScoreAppeal> sysDataReportingScoreAppeals = sysDataReportingScoreAppealMapper.selectSysDataReportingScoreAppealList(params);
        if(sysDataReportingScoreAppeals != null && !sysDataReportingScoreAppeals.isEmpty()){
            throw new RuntimeException("当前数据存在申诉的数据，无法删除");
        }
        return sysDataReportingMapper.deleteSysDataReportingByBaseIds(baseIds);
    }

    /**
     * 删除数据上报信息
     *
     * @param baseId 数据上报主键
     * @return 结果
     */
    @Override
    public int deleteSysDataReportingByBaseId(String baseId)
    {
        return sysDataReportingMapper.deleteSysDataReportingByBaseId(baseId);
    }

    /**
     * 市级审核数据
     * @param sysDataReporting
     * @return
     */
    @Override
    public AjaxResult cityCheckData(SysDataReporting sysDataReporting) {
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        if(Objects.isNull(sysUser)){
            return AjaxResult.warn("没有找到用户信息");
        }
        List<SysRole> roles = sysUser.getRoles();
        if(roles == null || roles.isEmpty()){
            return AjaxResult.warn("没有找到用户角色");
        }
        List<String> userRoleArgs = roles.stream().map(SysRole::getRoleKey).collect(Collectors.toList());
        if(!ArrayUtil.containsAny(userRoleArgs.toArray(), RoleContents.PROVINCE)){
            return AjaxResult.warn("您不是省级用户无权限审核数据");
        }
        SysDataReporting params = new SysDataReporting();
        params.setBaseId(sysDataReporting.getBaseId());
        params.setCheckStatus(sysDataReporting.getCheckStatus());
        if(StringUtils.isNotBlank(sysDataReporting.getRejection())){
            params.setRejection(sysDataReporting.getRejection());
        }
        sysDataReportingMapper.updateCheckStatus(params);
        return AjaxResult.success("审核完成");
    }


    private Map<String,String> result = new HashMap<String,String>();

    @PostConstruct
    public void init(){
        result.put("perMuGdp","全部工业增加值");
        result.put("preMuAla","规模以上工业增加值增速");
        result.put("preMuEcPt","制造业增值税、企业所得税等重点税收贡献情况");
        result.put("preMuEcTec","制造业增加值占 CDP 比重及提高幅度");
        result.put("lpvGdp","规模以上工业企业数量及增幅");
        result.put("lpvAvNumEmploy","工业投资增速");
        result.put("epResearchDevelop","工业技术改造投资增速");
        result.put("epOperatingRevenue","规模以上工业企业亩均税收");
        result.put("pollutionEmission","省级以上专精特新和单项冠军数量");
        result.put("pollutionGdp","能源原材料工业占规上工业增加值比重");
        result.put("compDevelopMvg","制造业贷款占各项贷款余额比重");
        result.put("compDevelopQr","规模以上工业企业 R&D 经费支出占营业收入比重");
        result.put("compDevelopEn","高技术产业产值占规模以上工业总产值比重");
        result.put("compDevelopRc","数字经济核心产业收入规模");
        result.put("compDevelopTo","规模以上工业企业新产品销售收入占规模以上工业营业收入比重");
        result.put("compDevelopProduc","规模以上工业单位增加值能耗降低率");
        result.put("innovLeadRdOr","PM2.5 平均浓度及同比改善率");
        result.put("innovLeadIp","省级以上绿色工业园区、工厂和供应链数量");
        result.put("innovLeadIs","绿色贷款余额占各项贷款余额比重");
        result.put("yytj","是否发生重大及以上生产安全责任事故、重大产品质量事件、重大及以上突发环境事件、统计数据不实问题");
    }

    @Override
    public AjaxResult selectDistrictInfo(String baseId) {
        SysDataReporting sysDataReporting = sysDataReportingMapper.selectSysDataReportingByBaseId(baseId);
        SysDataReporting zbScore = sysDataReportingScoreMapper.selectSysDataReportingByPkId(baseId);

        Map<String, Object> zbScoreMap = new HashMap<>(16);
        if(zbScore != null){
            zbScoreMap = BeanUtil.beanToMap(zbScore);
        }

        Map<String, Object> sysDataReportingMap = BeanUtil.beanToMap(sysDataReporting);
        List<SysZb> list = new ArrayList<>();

        for(Map.Entry<String,Object> item : sysDataReportingMap.entrySet()){
            String key = item.getKey();
            Object value = item.getValue();
            SysZb sysZb = new SysZb();
            if(result.containsKey(key)){

                if(!zbScoreMap.isEmpty()){
                    Object indexScore = zbScoreMap.get(key);
                    sysZb.setIndexScore((String) indexScore);
                }

                sysZb.setZbName(result.get(key));
                sysZb.setIndexCode(key);
                if(StringUtils.equals(key,"yytj")){
                    String yytjVa = (String)value;
                    if(StringUtils.equals(yytjVa,"0")){
                        sysZb.setEnterScore("否");
                    }else{
                        sysZb.setEnterScore("是");
                    }
                }else{
                    sysZb.setEnterScore((String)value);
                }

                list.add(sysZb);
            }
        }
        Map<String,Object> returnMap = new HashMap<>(16);
        returnMap.put("pkId",baseId);
//        returnMap.put("baseId",Objects.isNull(zbScore) ? "" : zbScore.getBaseId());
        returnMap.put("baseId",zbScoreMap.get("baseId"));
        returnMap.put("list",list);
        returnMap.put("totalScore",zbScoreMap.get("totalScore"));
        return AjaxResult.success(returnMap);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult saveDistrictScore(Map<String,Object> params) {

        List<HashMap<String,String>> sysZbs = (ArrayList)params.get("list");

        if(sysZbs == null || sysZbs.isEmpty()){
            return AjaxResult.warn("当前没有找到要保存打分的数据");
        }
        BigDecimal totalScoreBigDecimal = new BigDecimal(0);
        Map<String,String> result = new HashMap<>(16);
        for(Map<String,String> item : sysZbs){
            String indexCode = item.get("indexCode");
            String indexScore = item.get("indexScore");
            if(StringUtils.isNotBlank(indexScore)){
                //计算总数
                totalScoreBigDecimal = totalScoreBigDecimal.add(new BigDecimal(indexScore));
            }
            result.put(indexCode,indexScore);
        }
        result.put("pkId",sysZbs.get(0).get("pkId"));
        result.put("totalScore",String.valueOf(totalScoreBigDecimal.doubleValue()));
        result.put("baseId",StringUtils.isBlank(sysZbs.get(0).get("baseId")) ? IdUtils.simpleUUID() : sysZbs.get(0).get("baseId"));
        SysDataReporting sysDataReporting = BeanUtil.mapToBean(result, SysDataReporting.class, false, CopyOptions.create(SysDataReporting.class,true).ignoreNullValue());
        sysDataReporting.setEvaluationTime(DateUtils.getNowDate());
        if(StringUtils.equals(sysDataReporting.getYytj(),"1")){
            sysDataReporting.setTotalScore("0");
        }
        sysDataReportingScoreMapper.updateOrInsertScore(sysDataReporting);
        return AjaxResult.success("打分成功");
    }

    /**
     * 区县用户申诉分数
     * @param params
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult districtAppealScore(List<SysDataReportingScoreAppealOld> params) {
        if(params == null || params.isEmpty()){
            return AjaxResult.warn("没有找到有效的申诉数据");
        }
        String pkId = params.get(0).getPkId();

        //当前申诉数据的ID
        String baseId = IdUtils.simpleUUID();

        List<SysDataReportingScoreAppealFile> fileList = new ArrayList<>();

        Map<String,String> updateParams = new HashMap<>(16);
        for(SysDataReportingScoreAppealOld item : params){
            String indicatorName = item.getIndicatorName();
            String currentScore = item.getCurrentScore();
            String appealScore = item.getAppealScore();

            SysDataReportingScoreAppealFile sysDataReportingFile = item.getSysDataReportingFile();
            if(!Objects.isNull(sysDataReportingFile)){
                if(StringUtils.isNotBlank(sysDataReportingFile.getFilePath())){
                    sysDataReportingFile.setPkId(baseId);
                    sysDataReportingFile.setBaseId(IdUtils.simpleUUID());
                    sysDataReportingFile.setBaseCreateTime(DateUtils.getNowDate());
                    sysDataReportingFile.setBaseCreateBy(SecurityUtils.getUserId());
                    sysDataReportingFile.setFilePath("/file" + StrUtil.removePrefix(sysDataReportingFile.getFilePath(),fileDomain));
                    sysDataReportingFile.setIndexCode(indicatorName);
                    fileList.add(sysDataReportingFile);
                }
            }
            updateParams.put(indicatorName,currentScore);
            updateParams.put(indicatorName + "Appeal",appealScore);
        }

        if(!updateParams.isEmpty()){
            SysDataReportingScoreAppeal sysDataReportingScoreAppeal = BeanUtil.mapToBean(updateParams, SysDataReportingScoreAppeal.class, false, CopyOptions.create(SysDataReportingScoreAppeal.class, true).ignoreNullValue());

            sysDataReportingScoreAppeal.setBaseId(baseId);
            sysDataReportingScoreAppeal.setCheckStatus("0");
            sysDataReportingScoreAppeal.setPkId(pkId);
            //写入申诉数据
            sysDataReportingScoreAppealMapper.insertSysDataReportingScoreAppeal(sysDataReportingScoreAppeal);
            if(!fileList.isEmpty()){
                //写入申诉数据的文件信息
                sysDataReportingScoreAppealFileMapper.batchInserSysDataReportingScoreAppealFile(fileList);
            }
            return AjaxResult.success("提交成功");
        }
        return AjaxResult.warn("没有找到要保存的数据");
    }

    /**
     * 通过Id查询当前县有没有提交过申诉申请
     *
     * @param baseId
     * @return
     */
    @Override
    public AjaxResult selectDistrictAppealExist(String baseId) {
        SysDataReportingScoreAppeal sysDataReportingScoreAppeal = sysDataReportingScoreAppealMapper.selectDistrictAppealExist(baseId);
        if(Objects.isNull(sysDataReportingScoreAppeal)){
            return AjaxResult.success(true);
        }
        return AjaxResult.success(false);
    }

    @Override
    public void importXlsx(List<SysDataReporting> sysDataReportings) {
        Date nowDate = DateUtils.getNowDate();
        if(sysDataReportings != null && !sysDataReportings.isEmpty()){
            sysDataReportings.forEach(item -> {
                item.setBaseId(IdUtils.simpleUUID());
                item.setCheckStatus("1");
                item.setBaseCreateBy(SecurityUtils.getUserId());
                item.setBaseCreateTime(new Date());
                item.setYear(String.valueOf(DateUtil.year(nowDate) - 1));
                if(StringUtils.equals(item.getYytj(),"是")){
                    item.setYytj("1");
                }else if(StringUtils.equals(item.getYytj(),"否")){
                    item.setYytj("0");
                }
            });
            sysDataReportingMapper.batchInsert(sysDataReportings);
        }
    }
}
